Imports System.Drawing

''' <summary>
''' Base class for charts (not gauges). Types of charts may be added to a GraphChart as OverLays. 
''' All overlays are displayed in the order that they are added, and clicking on a point in the chart 
''' will return all data for all OverLays occupying that point.
''' </summary>
''' <remarks></remarks>
Public Class GraphChart
    Inherits Chart

    Private msChartName As String
    Private moNameColor As Color = Color.Black

    Private moFont As Font = New Font(System.Drawing.FontFamily.GenericSansSerif, 10)

    Private moXAxis As XAxis = Nothing
    Private moYAxis1 As YAxis = Nothing
    Private moYAxis2 As YAxis = Nothing

    Private moOverLays As New ArrayList
    Private moLegend As Legend = Nothing

    ''' <summary>
    ''' The chart must be painted on a graphic using the DrawChart method and 0,0 is 
    ''' used as the upper left-hand corner of the chart on the graphic.
    ''' </summary>
    ''' <param name="iWidth">Width of the generated chart image</param>
    ''' <param name="iHeight">Height of the generated chart image</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal iWidth As Integer, ByVal iHeight As Integer)
        MyBase.New(iWidth, iHeight)
    End Sub

    ''' <summary>
    ''' The ChartName property is the name of the chart to be displayed at the center top of the charting area.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property ChartName() As String
        Get
            Return msChartName
        End Get
        Set(ByVal value As String)
            msChartName = value
        End Set
    End Property

    Public Property NameColor() As Color
        Get
            Return moNameColor
        End Get
        Set(ByVal value As Color)
            moNameColor = value
        End Set
    End Property

    ''' <summary>
    ''' The Font property is the font to use when displaying the chart name.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property Font() As Font
        Get
            Return moFont
        End Get
        Set(ByVal value As Font)
            moFont = value
        End Set
    End Property

    ''' <summary>
    ''' Sets or gets the jChart.Legend object associated with the chart.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property Legend() As Legend
        Get
            Return moLegend
        End Get
        Set(ByVal value As Legend)
            moLegend = value
        End Set
    End Property

    ''' <summary>
    ''' The OverLays property exposes an ArrayList of chart types which will be layered atop each other in 
    ''' the order that they are arranged in the ArrayList.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property OverLays() As ArrayList
        Get
            Return moOverLays
        End Get
        Set(ByVal value As ArrayList)
            moOverLays = value
        End Set
    End Property

    ''' <summary>
    ''' The XAxis property describes the X Axis values and alignment of those values. The XAxis object should
    '''  be used for all chart types that are added to an instance of a GraphChart via the OverLays property.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property XAxis() As XAxis
        Get
            Return moXAxis
        End Get
        Set(ByVal value As XAxis)
            moXAxis = value
        End Set
    End Property

    ''' <summary>
    ''' The YAxis1 property describes the Y Axis values and alignment of those values on the left side of the chart. 
    ''' Chart types that are added to an instance of a GraphChart via the OverLays may reference either YAxis1 
    ''' (on the left) or YAxis2 (on the right). See the constructors for LineOverLay, StackedOverLay and 
    ''' StackedPieOverLay for more information.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property YAxis1() As YAxis
        Get
            Return moYAxis1
        End Get
        Set(ByVal value As YAxis)
            moYAxis1 = value
        End Set
    End Property

    ''' <summary>
    ''' The YAxis2 property describes the Y Axis values and alignment of those values on the right side of
    '''  the chart. Chart types that are added to an instance of a GraphChart via the OverLays may reference
    '''  either YAxis1 (on the left) or YAxis2 (on the right). See the constructors for LineOverLay, 
    ''' StackedOverLay and StackedPieOverLay for more information.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property YAxis2() As YAxis
        Get
            Return moYAxis2
        End Get
        Set(ByVal value As YAxis)
            moYAxis2 = value
        End Set
    End Property

    ''' <summary>
    ''' The DrawChart method draws the chart on a graphic.
    ''' </summary>
    ''' <param name="g"></param>
    ''' <remarks></remarks>
    Public Overrides Sub DrawChart(ByVal g As Graphics)
        If msChartName > "" Then
            Dim oSizeF As SizeF = g.MeasureString(msChartName, moFont)
            moChartDimensions.TitleHeight = oSizeF.Height * 2
        End If

        If Not moLegend Is Nothing Then
            If moLegend.OverLaysExist = False Then
                For Each oOverLay As Object In moOverLays
                    moLegend.AddOverlay(oOverLay)
                Next
            End If

            '---Make sure that there's enough room to show legend
            moLegend.RecalculateDimensions(g)
        End If

        '---Make sure that there's enough room to show axis and label
        If Not moXAxis Is Nothing Then
            moXAxis.RecalculateDimensions(g)
        End If

        If Not moYAxis1 Is Nothing Then
            moYAxis1.RecalculateDimensions(g)
        End If

        If Not moYAxis2 Is Nothing Then
            moYAxis2.RecalculateDimensions(g)
        End If

        moChartDimensions.DrawBackground(g)

        If Not moXAxis Is Nothing Then
            moXAxis.DrawXAxisLabelArea(g)
        End If

        If Not moYAxis1 Is Nothing Then
            moYAxis1.DrawYAxisLabelArea(g)
        End If

        If Not moYAxis2 Is Nothing Then
            moYAxis2.DrawYAxisLabelArea(g)
        End If

        For Each oOverLay As Object In moOverLays
            oOverLay.DrawChart(g)
        Next

        If Not moLegend Is Nothing Then
            moLegend.DrawLegend(g)
        End If

        If msChartName > "" Then
            DrawTitle(g)
        End If
    End Sub

    Private Sub DrawTitle(ByVal g As Graphics)
        Dim oSize As SizeF = g.MeasureString(msChartName, moFont)

        Dim iX As Integer = moChartDimensions.OuterX + moChartDimensions.OuterWidth / 2 - oSize.Width / 2

        g.DrawString(msChartName, moFont, New SolidBrush(moNameColor), iX, 10)
    End Sub

    ''' <summary>
    ''' The GetAllRegions function returns an ArrayList of jChart.RegionArea objects describing the location 
    ''' of all series values displayed on the chart. This function is helpful when constructing an imagemap 
    ''' for use with charts that offer drill-down to other reports.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property RegionList() As ArrayList
        Get
            Dim oFoundRegions As New ArrayList

            For iCurrentOverlay As Integer = moOverLays.Count - 1 To 0 Step -1

                With moOverLays(iCurrentOverlay)
                    For iCurrentRegion As Integer = .RegionList.Count - 1 To 0 Step -1
                        oFoundRegions.Add(.RegionList(iCurrentRegion))
                    Next
                End With

            Next

            Return oFoundRegions
        End Get
    End Property

    ''' <summary>
    ''' The RegionsAtCoordinate function returns an ArrayList with all series that occupy a given point 
    ''' within the chart, with the top-most series at position 0 in the array.
    ''' </summary>
    ''' <param name="x"></param>
    ''' <param name="y"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function RegionsAtCoordinate(ByVal x As Integer, ByVal y As Integer) As ArrayList
        Dim oFoundRegions As New ArrayList

        For Each oRegion As RegionArea In RegionList()
            If oRegion.SeriesRegion.IsVisible(x, y) Then
                oFoundRegions.Add(oRegion)
            End If
        Next

        Return oFoundRegions
    End Function
End Class
